/*
 * test.cpp
 *
 *  Created on: Nov 23, 2012
 *      Author: dan
 */


#include "Network.h"
#include "Barrier.h"
#include "Mutex.h"
#include "Print.hpp"

namespace {
	DebugPrint debug_print(true);
}
void testBarrier(Network* net, Network::Team* team, int teammem);
void testMutex(Network* net, Network::Team* team, int teammem);
void testMutex1(Network* net, Network::Team* team, int teammem);

int main(int ac, char** av) {
	using namespace std;
	boost::system::error_code error;
	Network::Team team;
	team.push_back(Network::Address("127.0.0.1","5001"));
	team.push_back(Network::Address("127.0.0.1","5002"));
	team.push_back(Network::Address("127.0.0.1","5003"));

	if(ac<=1) return 1;
	std::stringstream s; s<<av[1];
	int member; s>>member;
	std::cout<<"Member is "<<member<<std::endl;

	Network network(team[member]);


	//boost::thread testBarrierThread( boost::bind(testBarrier, &network, &team, member) );
	boost::thread testMutexThread( boost::bind(testMutex1, &network, &team, member) );

	network.connect(team);
}

void testBarrier(Network* net, Network::Team* team, int teammem){
	Barrier barrier_test(*net, *team, "test");

	PRINT("wait connections");
	barrier_test.waitConnection();
	PRINT("all team connected");
	int it = 1;
	while(true){
		PRINT("ITERATION #"<<it++);
		bool ok = barrier_test.wait();
		PRINT("CONTINUE: "<<(ok?"ok":"error"));
		if(!ok) break;
		PRINT("sleep. Hrrr... ");
		boost::this_thread::sleep(boost::posix_time::seconds(teammem*3));
		PRINT("week up");
	}
}

void testMutex(Network* net, Network::Team* team, int teammem){
	Mutex mutex_test(*net, *team, "test");
	mutex_test.debug_print.turn_on();

	PRINT("wait connections");
	mutex_test.waitConnection();
	PRINT("all team connected");
	int it = 1;
	while(true){
		PRINT("ITERATION #"<<it++);
		if( mutex_test.lock() ){
			PRINT("INSIDE CRITICAL SECTION");
			for(int i=0;i<10;i++){
				PRINT("i="<<i);
				boost::this_thread::sleep(boost::posix_time::seconds(1));
			}
			PRINT("OUTSIDE OF CRITICAL SECTION");
			mutex_test.unlock();
		}else{
			PRINT("ERROR: can not lock mutex");
			break;
		}
		PRINT("sleep. Hrrr... ");
		boost::this_thread::sleep(boost::posix_time::seconds(teammem*3));
		PRINT("week up");
	}
}

void testMutex1(Network* net, Network::Team* team, int teammem){
	Mutex mutex_test(*net, *team, "test");
	mutex_test.debug_print.turn_on();

	PRINT("wait connections");
	mutex_test.waitConnection();
	PRINT("all team connected");
	int it = 1;
	while(true){
		PRINT("ITERATION #"<<it++);
		try{
			ScopedLock<Mutex> lock(mutex_test);
			PRINT("INSIDE CRITICAL SECTION");
			for(int i=0;i<10;i++){
				PRINT("i="<<i);
				boost::this_thread::sleep(boost::posix_time::seconds(1));
			}
			PRINT("OUTSIDE OF CRITICAL SECTION");
			mutex_test.unlock();
		}catch(std::exception& ex){
			PRINT("ERROR: "<<ex.what());
			break;
		}
		PRINT("sleep. Hrrr... ");
		boost::this_thread::sleep(boost::posix_time::seconds(teammem*3));
		PRINT("week up");
	}
}


